/*
 *  CERunningString.cpp
 *  LID Library
 *
 *  Created by Alexander Trutchenko on 09/11/11.
 *  Copyright 2011 League of Independent Developers. All rights reserved.
 *
 */

#include "cocos2dx_extentions/controls/CERunningString.h"


using namespace cocos2d;

namespace cocosext {

/////////////////////////////////////////////////////
//
/** CERunningString 
* 
*/
/////////////////////////////////////////////////////

CERunningString * CERunningString::node(float runningSpeed)
{
	return CERunningString::node(runningSpeed, NULL, NULL);
}

CERunningString* CERunningString::node(float runningSpeed, cocos2d::CCNode* item, ...)
{
	va_list args;
	va_start(args,item);
	CERunningString *pRet = new CERunningString(runningSpeed);
	if (pRet && pRet->init(item, args))
	{
		pRet->autorelease();
		va_end(args);
		return pRet;
	}
	va_end(args);
	CC_SAFE_DELETE(pRet)
	return NULL;
}

/////////////////////////////////////////////////////
//Constructor, destructor, init

bool CERunningString::init(cocos2d::CCNode* item, va_list args)
{
    if (!CEScissoredRGBARecursiveNode::init())
        return false;

	_scrollableArea = CCNode::node();
	_scrollableArea->setContentSize(this->getContentSize());
	_scrollableArea->setAnchorPoint(ccp(0.f, 0.5f));
	_scrollableArea->setPosition(ccp(0.f, this->getContentSize().height/2.f));
	this->addChild(_scrollableArea, 0);

	if (item)
	{
		item->setAnchorPoint(ccp(0.f, 0.5f));
		_scrollableArea->addChild(item);
		item = va_arg(args, CCNode*);
		while (item != NULL)
		{
			item->setAnchorPoint(ccp(0.f, 0.5f));
			_scrollableArea->addChild(item);
			item = va_arg(args, CCNode*);
		}
	}

	return true;
}

/////////////////////////////////////////////////////
//Cocos2d interface
void CERunningString::setContentSize(const cocos2d::CCSize& contentSize)
{
	CEScissoredRGBARecursiveNode::setContentSize(contentSize);

	_scrollableArea->setPosition(ccp(_scrollableArea->getPosition().x, this->getContentSize().height/2.f));
	updateRunning();
}

/////////////////////////////////////////////////////
//Main interface

void CERunningString::startRunning()
{
	if (_isRunning)
		return;
	_isRunning = true;
	updateRunning();
}

void CERunningString::stopRunning()
{
	if (!_isRunning)
		return;
	_isRunning = false;
	updateRunning();
}

void CERunningString::pause()
{
	if (_pauseCounter == 0)
		pauseSchedulerAndActions();
	++_pauseCounter;
}

void CERunningString::resume()
{
	if (_pauseCounter == 0)
		return;
	--_pauseCounter;
	if (_pauseCounter == 0)
		resumeSchedulerAndActions();
}

void CERunningString::addItem(cocos2d::CCNode* item)
{
	_itemsOrder.push_back(item);

	addItemNode(item);
}
void CERunningString::insertItem(unsigned int orderIndex, cocos2d::CCNode* item)
{
	CENodeVector::iterator it = _itemsOrder.begin();
	if (_itemsOrder.size() >= orderIndex)
		it = _itemsOrder.end();
	else
		it += orderIndex;
	_itemsOrder.insert(it, item);

	addItemNode(item);
}
void CERunningString::removeItem(unsigned int orderIndex)
{
	if (_itemsOrder.size() >= orderIndex)
		return;
	CENodeVector::iterator it = _itemsOrder.begin() + orderIndex;
	_scrollableArea->removeChild(*it, true);
	_itemsOrder.erase(it);

	updateScrollableAreaSize();
	updateItemsPositions();
	updateRunning();
}

/////////////////////////////////////////////////////
// Protected interface

void CERunningString::addItemNode(cocos2d::CCNode* item)
{
	item->setAnchorPoint(ccp(0.f, 0.5f));
	_scrollableArea->addChild(item);
	
	updateScrollableAreaSize();
	updateItemsPositions();
	updateRunning();
}

void CERunningString::updateScrollableAreaSize()
{
	float width = 0.f;
	float height = 0.f;
	for (CENodeVector::const_iterator it = _itemsOrder.begin(); it != _itemsOrder.end(); ++it)
	{
		width += (*it)->getContentSize().width*(*it)->getScaleX();
		if (height < (*it)->getContentSize().height*(*it)->getScaleY())
			height = (*it)->getContentSize().height*(*it)->getScaleY();
	}
	_scrollableArea->setContentSize(CCSize(width, height));
}

void CERunningString::updateItemsPositions()
{
	CCPoint pos(0.f, _scrollableArea->getContentSize().height/2.f);
	for (CENodeVector::const_iterator it = _itemsOrder.begin(); it != _itemsOrder.end(); ++it)
	{
		(*it)->setPosition(pos);
		pos.x += (*it)->getContentSize().width*(*it)->getScaleX();
	}
}

void CERunningString::updateRunning()
{
	if (_scrollableArea->getContentSize().width > this->getContentSize().width)
	{
		if (_isRunning)
		{
			_scrollableArea->stopAllActions();
			_isMovingAction = true;

			_scrollableArea->setPosition(ccp(0.f, this->getContentSize().height/2.f));

//			_scrollableArea->runAction(CCMoveTo::actionWithDuration(_scrollableArea->getContentSize().width/_runningSpeed, ccp(-_scrollableArea->getContentSize().width, _scrollableArea->getPosition().y)));
			
			_scrollableArea->runAction(CCSequence::actions(CCMoveTo::actionWithDuration(_scrollableArea->getContentSize().width/_runningSpeed, ccp(-_scrollableArea->getContentSize().width, _scrollableArea->getPosition().y))
														   , CCRepeat::actionWithAction(CCSequence::actions(CCPlace::actionWithPosition(ccp(this->getContentSize().width, _scrollableArea->getPosition().y))
											  			  													, CCMoveTo::actionWithDuration((_scrollableArea->getContentSize().width + this->getContentSize().width)/_runningSpeed, ccp(-_scrollableArea->getContentSize().width, _scrollableArea->getPosition().y))
																											, NULL), INT_MAX)
														   , NULL));
			
		}
		else
		{
		if (_isMovingAction)
			{
				_scrollableArea->stopAllActions();
				_isMovingAction = false;
				_scrollableArea->setPosition(ccp(0.f, this->getContentSize().height/2.f));
			}
		}
	}
	else
	{
		if (_isMovingAction)
		{
			_scrollableArea->stopAllActions();
			_isMovingAction = false;
			_scrollableArea->setPosition(ccp(0.f, this->getContentSize().height/2.f));
		}
	}
}

}; // end namespace cocosext

